package com.whut.transportation.network;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;

import com.whut.transportation.utils.CommonUtil;
import com.whut.transportation.utils.FormFile;
import com.whut.transportation.utils.MyLog;
/**
 * 用于上传文件
 * @author yuliyan
 *
 */
public class WebServiceManager implements Runnable {
	private Context context;
	private RequestListener listener;
	private Thread currentRequest = null;
	private WebServiceRequestVo requestVo;
	private static final String ENCODING = "UTF-8";

	public WebServiceManager(Context mContext, RequestListener mListener,
			WebServiceRequestVo vo) {
		this.context = mContext;
		this.listener = mListener;
		this.requestVo = vo;
	}

	public void request() {
		currentRequest = new Thread(this);
		currentRequest.start();
	}
	/**
	 * 对请求的字符串进行编码
	 * 
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String requestEncodeStr(String requestStr)
			throws UnsupportedEncodingException {
		return URLEncoder.encode(requestStr, ENCODING);
	}
	public void run() {
		// 0：无网络 1：WIFI 2：CMWAP 3：CMNET
		int netType = CommonUtil.isNetworkAvailable(context);
		if (netType != 0) {
			sentPost();
		} else {
			listener.action(RequestListener.EVENT_NOT_NETWORD, null);
		}
	}

	private void sentPost() {
		try {
			post(requestVo.requestUrl,requestVo.requestDataMap, requestVo.formFile);
		}  catch (SocketException e) {
			e.printStackTrace();
			listener.action(RequestListener.EVENT_CLOSE_SOCKET, null);
		} catch (SocketTimeoutException e) {
			e.printStackTrace();
			listener.action(RequestListener.EVENT_NETWORD_EEEOR, null);
		} catch (IOException e) {
			e.printStackTrace();
			listener.action(RequestListener.EVENT_GET_DATA_EEEOR, null);
		} catch (Exception e) {
			e.printStackTrace();
			listener.action(RequestListener.EVENT_NETWORD_EEEOR, null);
		}
	}
	public void post(String path, Map<String, String> params, FormFile[] files) throws Exception{     
        final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线
        final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志
        
        int fileDataLength = 0;
        for(FormFile uploadFile : files){//得到文件类型数据的总长度
        	StringBuilder fileExplain = new StringBuilder();
 	        fileExplain.append("--");
 	        fileExplain.append(BOUNDARY);
 	        fileExplain.append("\r\n");
 	        fileExplain.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
 	        fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
 	        fileDataLength += fileExplain.length();
        	if(uploadFile.getInStream()!=null){
        		fileDataLength += uploadFile.getFile().length();
	 	    }else{
	 	    	fileDataLength += uploadFile.getData().length;
	 	    }
        	fileDataLength += "\r\n".length();
        }
        StringBuilder textEntity = new StringBuilder();
        
        MyLog.i("msg", "222"+String.valueOf(params.size()));
        
        for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型参数的实体数据
            textEntity.append("--");
            textEntity.append(BOUNDARY);
            textEntity.append("\r\n");
            textEntity.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
            textEntity.append(entry.getValue());
            textEntity.append("\r\n");
        }
        //计算传输给服务器的实体数据总长度
        int dataLength = textEntity.toString().getBytes().length + fileDataLength +  endline.getBytes().length;
        
        URL url = new URL(path);
        int port = url.getPort()==-1 ? 80 : url.getPort();
        Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);	       
        OutputStream outStream = socket.getOutputStream();
        //下面完成HTTP请求头的发送
        String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";
        outStream.write(requestmethod.getBytes());
        String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";
        outStream.write(accept.getBytes());
        String language = "Accept-Language: zh-CN\r\n";
        outStream.write(language.getBytes());
        String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ "\r\n";
        outStream.write(contenttype.getBytes());
        String contentlength = "Content-Length: "+ dataLength + "\r\n";
        outStream.write(contentlength.getBytes());
        String alive = "Connection: Keep-Alive\r\n";
        outStream.write(alive.getBytes());
        String host = "Host: "+ url.getHost() +":"+ port +"\r\n";
        outStream.write(host.getBytes());
        //写完HTTP请求头后根据HTTP协议再写一个回车换行
        outStream.write("\r\n".getBytes());
        //把所有文本类型的实体数据发送出来
        outStream.write(textEntity.toString().getBytes());	       
        //把所有文件类型的实体数据发送出来
        for(FormFile uploadFile : files){
        	StringBuilder fileEntity = new StringBuilder();
 	        fileEntity.append("--");
 	        fileEntity.append(BOUNDARY);
 	        fileEntity.append("\r\n");
 	        fileEntity.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
 	        fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
 	        outStream.write(fileEntity.toString().getBytes());
 	        if(uploadFile.getInStream()!=null){
 	        	byte[] buffer = new byte[1024];
 	        	int len = 0;
 	        	while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1){
 	        		outStream.write(buffer, 0, len);
 	        	}
 	        	uploadFile.getInStream().close();
 	        }else{
 	        	outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);
 	        }
 	        outStream.write("\r\n".getBytes());
        }
        //下面发送数据结束标志，表示数据已经结束
        outStream.write(endline.getBytes());
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        if(reader.readLine().indexOf("404")==-1){//读取web服务器返回的数据，判断请求码是否为200，如果不是200，代表请求失败
        	listener.action(RequestListener.EVENT_GET_DATA_SUCCESS, 
        			readStream(new ByteArrayInputStream("{result:{message:1}}".getBytes("UTF-8"))));
        }
        outStream.flush();
        outStream.close();
        reader.close();
        socket.close();
	}
	
	
	/**
	 * 读取数据
	 * 
	 * @param inStream
	 *            输入流
	 * @return
	 * @throws Exception
	 */
	private Object readStream(InputStream inStream) throws Exception {
		String result;
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		result = new String(outStream.toByteArray(), ENCODING);
		MyLog.i("response", result);
		outStream.close();
		inStream.close();
		if(requestVo.parser == null) {
			return new HashMap<String, Object>();
		}
		return requestVo.parser.parseJSON(result);
	}
}
